#include <math.h>
#include "conditions.h"
#include "core/value.h"

using namespace Commands;
using namespace Commands::Core;

///------------------------[ Condition ]---------------------------------------
Condition::Condition()
: conditionResult(true)
{}
//-----------------------------------------------------------------------------
Condition::~Condition()
{}
//-----------------------------------------------------------------------------
bool Condition::IsFinished(void) const
{
    return true;
}
//-----------------------------------------------------------------------------
void Condition::Accept(Core::Inspector& inspector)
{}
///--------------------------[ True ]-----------------------------------------
True::True()
{}
//-----------------------------------------------------------------------------
True::~True()
{}
//-----------------------------------------------------------------------------
True* True::Copy(void) const
{
    return new True();
}
//-----------------------------------------------------------------------------
float True::Execute(const float seconds)
{
    return 0.0f;
}
///--------------------------[ False ]-----------------------------------------
False::False()
{
    conditionResult = false;
}
//-----------------------------------------------------------------------------
False::~False()
{}
//-----------------------------------------------------------------------------
False* False::Copy(void) const
{
    return new False();
}
//-----------------------------------------------------------------------------
float False::Execute(const float seconds)
{
    return 0.0f;
}
///-----------------------[ Comparision ]--------------------------------------
Comparision::Comparision()
: left(0l)
, right(0l)
{}
//-----------------------------------------------------------------------------
Comparision::Comparision(float left, float right)
: left(new Value(left))
, right(new Value(right))
{}
//-----------------------------------------------------------------------------
Comparision::Comparision(const Core::Value& left, float right)
: left(left.Copy())
, right(new Value(right))
{}
//-----------------------------------------------------------------------------
Comparision::Comparision(const float left, Core::Value& right)
: left(new Value(left))
, right(right.Copy())
{}
//-----------------------------------------------------------------------------
Comparision::Comparision(const Core::Value& left, const Core::Value right)
: left(left.Copy())
, right(right.Copy())
{}
//-----------------------------------------------------------------------------
Comparision::~Comparision()
{
    if(left) delete left;
    if(right) delete right;
}
///----------------------------[ Eq ]------------------------------------------
Eq::Eq()
{}
//-----------------------------------------------------------------------------
Eq::Eq(float left, float right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Eq::Eq(const Core::Value& left, float right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Eq::Eq(const float left, Core::Value& right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Eq::Eq(const Core::Value& left, const Core::Value right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Eq::~Eq()
{}
//-----------------------------------------------------------------------------
Eq* Eq::Copy(void) const
{
    return new Eq(*left, *right);
}
//-----------------------------------------------------------------------------
float Eq::Execute(const float seconds)
{
    left->Execute(seconds);
    right->Execute(seconds);
    conditionResult = (fabs(left->GetValue() - right->GetValue()) < 0.00001);
    return 0.0f;
}
///----------------------------[ Ge ]------------------------------------------
Ge::Ge()
{}
//-----------------------------------------------------------------------------
Ge::Ge(float left, float right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Ge::Ge(const Core::Value& left, float right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Ge::Ge(const float left, Core::Value& right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Ge::Ge(const Core::Value& left, const Core::Value right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Ge::~Ge()
{}
//-----------------------------------------------------------------------------
Ge* Ge::Copy(void) const
{
    return new Ge(*left, *right);
}
//-----------------------------------------------------------------------------
float Ge::Execute(const float seconds)
{
    left->Execute(seconds);
    right->Execute(seconds);
    conditionResult = (left->GetValue() >= right->GetValue());
    return 0.0f;
}
///----------------------------[ Gt ]------------------------------------------
Gt::Gt()
{}
//-----------------------------------------------------------------------------
Gt::Gt(float left, float right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Gt::Gt(const Core::Value& left, float right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Gt::Gt(const float left, Core::Value& right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Gt::Gt(const Core::Value& left, const Core::Value right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Gt::~Gt()
{}
//-----------------------------------------------------------------------------
Gt* Gt::Copy(void) const
{
    return new Gt(*left, *right);
}
//-----------------------------------------------------------------------------
float Gt::Execute(const float seconds)
{
    left->Execute(seconds);
    right->Execute(seconds);
    conditionResult = (left->GetValue() > right->GetValue());
    return 0.0f;
}
///----------------------------[ Le ]------------------------------------------
Le::Le()
{}
//-----------------------------------------------------------------------------
Le::Le(float left, float right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Le::Le(const Core::Value& left, float right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Le::Le(const float left, Core::Value& right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Le::Le(const Core::Value& left, const Core::Value right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Le::~Le()
{}
//-----------------------------------------------------------------------------
Le* Le::Copy(void) const
{
    return new Le(*left, *right);
}
//-----------------------------------------------------------------------------
float Le::Execute(const float seconds)
{
    left->Execute(seconds);
    right->Execute(seconds);
    conditionResult = (left->GetValue() <= right->GetValue());
    return 0.0f;
}
///----------------------------[ Lt ]------------------------------------------
Lt::Lt()
{}
//-----------------------------------------------------------------------------
Lt::Lt(float left, float right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Lt::Lt(const Core::Value& left, float right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Lt::Lt(const float left, Core::Value& right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Lt::Lt(const Core::Value& left, const Core::Value right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Lt::~Lt()
{}
//-----------------------------------------------------------------------------
Lt* Lt::Copy(void) const
{
    return new Lt(*left, *right);
}
//-----------------------------------------------------------------------------
float Lt::Execute(const float seconds)
{
    left->Execute(seconds);
    right->Execute(seconds);
    conditionResult = (left->GetValue() < right->GetValue());
    return 0.0f;
}
///----------------------------[ Ne ]------------------------------------------
Ne::Ne()
{}
//-----------------------------------------------------------------------------
Ne::Ne(float left, float right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Ne::Ne(const Core::Value& left, float right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Ne::Ne(const float left, Core::Value& right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Ne::Ne(const Core::Value& left, const Core::Value right)
: Comparision(left, right)
{}
//-----------------------------------------------------------------------------
Ne::~Ne()
{}
//-----------------------------------------------------------------------------
Ne* Ne::Copy(void) const
{
    return new Ne(*left, *right);
}
//-----------------------------------------------------------------------------
float Ne::Execute(const float seconds)
{
    left->Execute(seconds);
    right->Execute(seconds);
    conditionResult = (fabs(left->GetValue() - right->GetValue()) > 0.00001);
    return 0.0f;
}
